/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.toolkit.shape.annotation.impl;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import org.apache.log4j.Logger;

import who.tmap.bo.cd.CDPointSymbols;
import who.tmap.bo.cd.CDTypes;
import who.tmap.services.TextureService;
import who.tmap.toolkit.impl.ShapeHelper;

public class LegendSample {
	
    private static Logger logger = Logger.getLogger(LegendSample.class); 		
	
	private Point2D pt;
	private Color color;
	private TexturePaint texturePaint;
	private int cdPointSymbol;
	private int cdType;
	// For Proportional Symbols
	private double psSize;
	
	private static TextureService textureHelper =TextureService.getInstance();
	private ShapeHelper shapeHelper =new ShapeHelper();	
	private ImageHelper imageHelper =new ImageHelper();
	
	public LegendSample( Point2D pt, Color color, TexturePaint texturePaint, int cdPointSymbol, Image img ) {
		this.pt =pt;
		this.color =color;
		this.texturePaint =texturePaint;
		this.cdPointSymbol =cdPointSymbol;
		
		if ( cdPointSymbol == -1 ) {
			cdType =CDTypes.COLOR_PATTERN;
		} else {
			cdType =CDTypes.POINT;
			imageHelper.setImage( img );
		}
	}
	
	/**
	 * For Proportional Symbols
	 * @param pt
	 * @param psSize
	 * @param color
	 * @param cdPointSymbol
	 */
	public LegendSample( Point2D pt, double psSize ) {
		this.pt =pt;
		this.color =Color.BLACK;
		this.texturePaint =textureHelper.getTexturePaint()[ 0 ];
		this.cdPointSymbol =CDPointSymbols.CIRCLE;
		this.psSize =psSize;
		this.cdType =CDTypes.PROPORTIONAL_SYMBOLS;
	}		
	
	/**
	 * For Proportional Symbols
	 * @param g2d
	 */
	public void draw( Graphics2D g2d ) {
		draw( g2d, 0, 0, 0, 0 );
	}
	
	public void draw( Graphics2D g2d, double width, double height, double screenToMapFactor, double zoomFactor ) {

		// Special case for proportional symbols 
		// as creating a new area seems to ignore stroke width
		// It's probably a Java2D issue
		if ( cdType == CDTypes.PROPORTIONAL_SYMBOLS ) {
			g2d.draw( shapeHelper.makeSymbol( pt, psSize, cdPointSymbol, ShapeHelper.AS_SPECIFIED ) );

	    // Scale a bitmap sample for CD Point legend
		} else if ( cdType == CDTypes.POINT && cdPointSymbol == CDPointSymbols.BITMAP ) {
						
		    double factor =screenToMapFactor * zoomFactor / 100d;
		    
		    Image theImage =null;
		    if ( width != imageHelper.getWidth() || height != imageHelper.getHeight() ) {
		    	theImage =imageHelper.computeResizedImage( width / factor, height / factor );
		    } else {
		    	theImage =imageHelper.getImage();
		    }
		    
		    AffineTransform at =new AffineTransform();
			
		    at.translate( pt.getX(), pt.getY() );
		    at.scale( factor, factor );
		    
		    g2d.drawImage( theImage, at, null );
			
		} else {
			
			Shape shape =null;			
			
			// Color/Pattern sample is a rectangle
			if ( cdType == CDTypes.COLOR_PATTERN ) {
				Rectangle2D rect =new Rectangle2D.Double( pt.getX(), pt.getY(), width, height );
				shape =rect;
				
				g2d.draw( shape );
			// Point sample
			} else if ( cdType == CDTypes.POINT ) {
				shape =shapeHelper.makeSymbol( pt, width, cdPointSymbol, ShapeHelper.AS_SPECIFIED );
			}
			
			Area area =new Area( shape );
			
			AffineTransform prevTransform =g2d.getTransform();
			Area newArea = area.createTransformedArea( prevTransform );
			
			g2d.setTransform( new AffineTransform() );
			
			Composite prevComp =g2d.getComposite();
			Color prevColor =g2d.getColor();
			Paint prevPaint =g2d.getPaint();
			
			g2d.setColor( color );	
			
			g2d.fill( newArea );	
			
			if ( texturePaint != null ) {
				g2d.setComposite( AlphaComposite.getInstance( TextureService.CD_ALPHA_RULE, 
															  TextureService.CD_ALPHA_COMPOSITE ) ); 
			
				g2d.setPaint( texturePaint );
			}
			
			g2d.draw( newArea );
			
			g2d.fill( newArea );
			
			g2d.setTransform( prevTransform );
			g2d.setPaint( prevPaint );
			g2d.setColor( prevColor );
			g2d.setComposite( prevComp );	
		}
		
	}
	
	public Point2D getPt() {
		return pt;
	}

	public double getPsSize() {
		return psSize;
	}
	
}
